package cn.ljlao.mall.product.goods.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.ljlao.common.constant.ProductConstant;
import cn.ljlao.common.utils.PageUtils;
import cn.ljlao.common.utils.Query;
import cn.ljlao.mall.product.goods.dao.AttrAttrgroupRelationDao;
import cn.ljlao.mall.product.goods.dao.AttrGroupDao;
import cn.ljlao.mall.product.goods.dao.CategoryDao;
import cn.ljlao.mall.product.goods.entity.AttrAttrgroupRelationEntity;
import cn.ljlao.mall.product.goods.entity.AttrGroupEntity;
import cn.ljlao.mall.product.goods.entity.CategoryEntity;
import cn.ljlao.mall.product.goods.feign.SpuBoundsFeign;
import cn.ljlao.mall.product.goods.service.AttrAttrgroupRelationService;
import cn.ljlao.mall.product.goods.service.CategoryService;
import cn.ljlao.mall.product.goods.vo.AttrRspVo;
import cn.ljlao.mall.product.goods.vo.AttrVo;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.GlobalStatus;
import io.seata.core.model.TransactionManager;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.TransactionManagerHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.ljlao.mall.product.goods.dao.AttrDao;
import cn.ljlao.mall.product.goods.entity.AttrEntity;
import cn.ljlao.mall.product.goods.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    AttrAttrgroupRelationDao attrAttrgroupRelationDao;


    @Autowired
    AttrGroupDao attrGroupDao;

    @Autowired
    CategoryDao categoryDao;

    @Autowired
    CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void saveDetails(AttrVo attr) {

        //创建对象
        AttrEntity attrEntity = new AttrEntity();
        //copy 属性
        BeanUtils.copyProperties(attr, attrEntity);
        //保存入库
        this.save(attrEntity);

        if (ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == attr.getAttrType() && attr.getAttrGroupId() != null) {
            //关联关系保存入库
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);
        }


    }

    /**
     * 查询列表
     *
     * @param params
     * @param catelogId
     * @param type
     * @return
     */
    @Override
    public PageUtils baseList(Map<String, Object> params, Long catelogId, String type) {

        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("attr_type", "base".equalsIgnoreCase(type) ? 1 : 0);
        //添加条件id
        if (catelogId != 0) {
            wrapper.eq("catelog_id", catelogId);
        }
        //获取模糊查询参数
        String key = MapUtil.get(params, "key", String.class);

        if (!StringUtils.isEmpty(key)) { //添加模糊查询条件
            wrapper.and((obj) -> {
                obj.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        //分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );
        //获取结果集
        List<AttrEntity> records = page.getRecords();
        //遍历 筛选
        List<AttrRspVo> attrRspVoList = records.stream().map((attrEntity -> {
            //创建相应对象
            AttrRspVo attrRspVo = new AttrRspVo();
            //拷贝属性
            BeanUtils.copyProperties(attrEntity, attrRspVo);
            if ("base".equalsIgnoreCase(type)) {
                //查询中间表关系 获得属性分组id
                AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrRspVo.getAttrId()));
                if (relationEntity != null) {
                    //根据属性分组 id 获得组名
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                    if (attrGroupEntity != null) {
                        attrRspVo.setGroupName(attrGroupEntity.getAttrGroupName());
                    }
                }
            }
            //根据属性id 获得属性名称
            CategoryEntity categoryEntity = categoryDao.selectById(attrRspVo.getCatelogId());
            if (categoryEntity != null) {
                attrRspVo.setCatelogName(categoryEntity.getName());

            }
            //返回
            return attrRspVo;
        })).collect(Collectors.toList());

        //重新封装结果集
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(attrRspVoList);

        return pageUtils;
    }

    /**
     * 获得规格详情
     *
     * @param attrId
     * @return
     */
    @Override
    public AttrRspVo getInfo(Long attrId) {
        AttrRspVo attrRspVo = new AttrRspVo();
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity, attrRspVo);
        if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            //查询中间表关系 获得属性分组id
            AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationService.getOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrRspVo.getAttrId()));
            if (relationEntity != null) {
                //根据属性分组 id 获得组名
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
                if (attrGroupEntity != null) {
                    attrRspVo.setGroupName(attrGroupEntity.getAttrGroupName());
                    attrRspVo.setAttrGroupId(attrGroupEntity.getAttrGroupId());
                }
            }
        }
        //根据属性id 获得属性名称
        CategoryEntity categoryEntity = categoryDao.selectById(attrRspVo.getCatelogId());
        if (categoryEntity != null) {
            attrRspVo.setCatelogName(categoryEntity.getName());

        }
        //获取分类的路径 path
        Long[] catePath = categoryService.getCatePath(attrRspVo.getCatelogId());
        attrRspVo.setCatelogPath(catePath);

        return attrRspVo;
    }

    /**
     * 修改
     *
     * @param attr
     */
    @Override
    public void updateByDetial(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        //先修改自己
        this.updateById(attrEntity);
        //关联表关系
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrId(attr.getAttrId());
        relationEntity.setAttrGroupId(attr.getAttrGroupId());
        //查询关联表有没有
        int count = attrAttrgroupRelationService.count(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
        //有就更新没有就插入
        if (count > 0) {
            attrAttrgroupRelationService.update(relationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
        } else {
            attrAttrgroupRelationService.save(relationEntity);
        }

    }

    /**
     * 根据分组id 找到所有基本属性
     *
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> attrRelation(Long attrgroupId) {
        // 获取分组的所有attr id
        List<AttrAttrgroupRelationEntity> list = attrAttrgroupRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        if (list.isEmpty() || list == null) {
            return null;
        }
        List<Long> collect = list.stream().map(
                (obj) -> {
                    Long attrId = obj.getAttrId();
                    return attrId;
                }
        ).collect(Collectors.toList());

        List<AttrEntity> attrEntities = this.listByIds(collect);


        return attrEntities;
    }

    @Override
    public void deleteAttrRelation(List<AttrAttrgroupRelationEntity> list) {
        attrAttrgroupRelationDao.deleteAttrRelation(list);
    }

    @Override
    public PageUtils noAttrRelation(Long attrgroupId, Map<String, Object> params) {
        //1.根据分组id 查询对应的分类id
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        // 分类id
        Long catelogId = attrGroupEntity.getCatelogId();
        // 根据分类id 查询所有的分组id
        List<AttrGroupEntity> groupEntities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        // 获取所有的分组id
        List<Long> collect = groupEntities.stream().map((item) -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());
        //非空校验

        if (collect.isEmpty() || collect == null) {
            return null;
        }

        // 根据查出的所有的分组id  查询关联表中绑定的 attr_id (属性id)
        List<AttrAttrgroupRelationEntity> attrGroupId = attrAttrgroupRelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", collect));

        List<Long> attrIds = attrGroupId.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        //非空校验


        //根据这些属性id , 找出没绑定的属性id 分页查询
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if (!attrIds.isEmpty() && attrIds != null) {
            wrapper.notIn("attr_id", attrIds);
        }

        //判断条件查询
        String key = (String) params.get("key");
        if (!key.isEmpty()) {
            wrapper.and((w) -> {
                w.eq("attr_id", key)
                        .or().like("attr_name", key);
            });
        }

        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);

        PageUtils pageUtils = new PageUtils(page);

        return pageUtils;


    }

    /**
     * 根据属性 集合 获取 带查询的 属性集合
     *
     * @param attrIds
     * @return
     */
    @Override
    public List<Long> selectSearchAttrs(List<Long> attrIds) {

        List<AttrEntity> list = baseMapper.selectSearchAttrs(attrIds);
        if (list == null && list.size() == 0) {
            return null;
        }
        return list.stream().map(item -> item.getAttrId()).collect(Collectors.toList());
    }


    @Autowired
    SpuBoundsFeign spuBoundsFeign;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    AttrDao attrDao;

    @DS("test")
    @Transactional
    @GlobalTransactional
    public void saveaab(){
        attrDao.ttt();
        attrAttrgroupRelationService.ttt();
        int i = 1/0;
    }


    @Autowired
    private DataSource dataSource;


    public void saveaa() {
        List<Connection> list = new ArrayList<>();
        try {
            DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
            DynamicDataSourceContextHolder.push("master");//手动切换
            DataSource source = ds.getCurrentDataSources().get("master");
            Connection conn = DataSourceUtils.getConnection(source);
            conn.setAutoCommit(false);
            conn.prepareStatement("INSERT INTO `aa`(`aaa`) VALUES ('3')").executeUpdate();
            conn.commit();//没有异常就提交
            list.add(conn);
            DynamicDataSourceContextHolder.push("test");//手动切换
            DataSource test = ds.getCurrentDataSources().get("test");
            Connection conn2 = DataSourceUtils.getConnection(test);
            conn2.setAutoCommit(false);
            PreparedStatement statement = conn2.prepareStatement("INSERT INTO `student`( `name`, `tid`) VALUES ( ?, ?)");
            statement.setString(1,"张三");
            statement.setString(2,"李四");
            statement.executeUpdate();
            conn2.commit();
            list.add(conn2);
            //int i = 1 / 0;
        } catch (Exception e) {
            for (Connection connection : list) {
                try {
                    connection.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        } finally {
            for (Connection connection : list) {
                try {
                    connection.setAutoCommit(true);
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}


